<template>
  <el-form :model="formDataModel" ref="LeaveForm" :rules="rules" :disabled="disabled" label-position="left" label-width="80px"
           size="default" @submit.prevent>
    <el-form-item label="请假类型" prop="radio82983" class="required" v-show="formHidden.radio82983">
      <el-radio-group v-model="formDataModel.radio82983" :disabled="formDisabled.radio82983">
        <el-radio-button v-for="(item, index) in radio82983Options" :key="index" :label="item.value"
                         style="{display: inline}">{{item.label}}</el-radio-button>
      </el-radio-group>
    </el-form-item>
    <el-form-item label="请假日期" prop="daterange60173" class="required" v-show="formHidden.daterange60173">
      <el-date-picker is-range v-model="formDataModel.daterange60173" :disabled="formDisabled.daterange60173" type="daterange" class="full-width-input"
                      format="YYYY-MM-DD" value-format="YYYY-MM-DD" clearable @change="onDateChange"></el-date-picker>
    </el-form-item>
    <el-form-item label="请假天数" prop="day" class="required module-input-width" v-show="formHidden.day">
      <el-input-number v-model="formDataModel.day" :disabled="formDisabled.day" type="text"></el-input-number>
    </el-form-item>
    <el-form-item label="请假备注" prop="textarea47449" class="required module-width" v-show="formHidden.textarea47449">
      <el-input type="textarea" v-model="formDataModel.textarea47449" :disabled="formDisabled.textarea47449" rows="3"></el-input>
    </el-form-item>
  </el-form>

</template>

<script setup name="LeaveForm">
import {deepCloneObj} from "@/utils";
const { proxy } = getCurrentInstance();
const disabled = ref(false);
const data = reactive({
  // 表单数据初始值
  formDataModel: {
    radio82983: "1",
    daterange60173: null,
    day: "",
    textarea47449: "",
  },
  // 指定表单组件名称和类型
  formDataModelType: {
    radio82983: "radio",
    daterange60173: "date-range",
    day: "input",
    textarea47449: "textarea",
  },
  // 指定表单组件是否禁用
  formDisabled: {
    radio82983: false,
    daterange60173: false,
    day: true,
    textarea47449: false,
  },
  // 指定表单组件是否隐藏
  formHidden: {
    radio82983: true,
    daterange60173: true,
    day: true,
    textarea47449: true,
  },
  // 指定表单组件属性列表,type: invisible:不可见 readonly:只读 readwrite:可读写
  fieldWidgets: [
    {
      id: 'radio82983',
      label: '请假类型',
      required: true, // 是否必填
      type: 'readwrite', // 默认设置为可读写
    },
    {
      id: 'daterange60173',
      label: '请假日期',
      required: true, // 是否必填
      type: 'readwrite', // 默认设置为可读写
    },
    {
      id: 'day',
      label: '请假天数',
      required: true, // 是否必填
      type: 'readonly', // 默认设置为只读
    },
    {
      id: 'textarea47449',
      label: '请假备注',
      required: false, // 是否必填
      type:'readwrite', // 默认设置为可读写
    },
  ],
  // 表单校验规则
  rules: {
    radio82983: [{
      required: true,
      message: '字段值不可为空',
    }],
    daterange60173: [{
      required: true,
      message: '字段值不可为空',
    }],
    day: [{
      required: true,
      message: '字段值不可为空',
    }, {
      pattern: /^[-]?\d+(\.\d+)?$/,
      trigger: ['blur', 'change'],
      message: ''
    }],
    textarea47449: [{
      required: true,
      message: '字段值不可为空',
    }],
  },
  radio82983Options: [{
    "value": "1",
    "label": "事假"
  }, {
    "value": "2",
    "label": "病假"
  }, {
    "value": "3",
    "label": "婚假"
  }, {
    "value": 4,
    "label": "产假"
  }, {
    "value": 5,
    "label": "年假"
  }],
})

const { formDataModel, formDataModelType, rules, radio82983Options, formDisabled, formHidden, fieldWidgets} = toRefs(data);

function submitForm() {
  proxy.$refs['vForm'].validate(valid => {
    if (!valid) return
    //TODO: 提交表单
  })
}

function resetForm() {
  proxy.$refs['vForm'].resetFields()
}

// 时间范围改变事件
function onDateChange(dateRegion) {
  formDataModel.value.day = calculateDateInterval(dateRegion);
}

//计算时间间隔
function calculateDateInterval(dateRegion) {
  if (dateRegion) {
    const day1 = dateRegion[0];
    const day2 = dateRegion[1];
    let startTime = new Date(day1); // 开始时间
    let endTime = new Date(day2); // 结束时间
    const dateInterval = endTime.getTime() - startTime.getTime();  //获取时间差毫秒
    //计算出相差天数
    return Math.floor(dateInterval / (24 * 60 * 60 * 1000));
  }
}

/* --- 自定义组件必须实现方法 ---start */
// 设置表单数据
function setFormData(formData, formDisabled) {
  if (formDisabled) {
    disabled.value = formDisabled
  }
  Object.keys(formDataModel.value).forEach(propName => {
    if (!!formData && formData.hasOwnProperty(propName)) {
      formDataModel.value[propName] = deepCloneObj(formData[propName])
    }
  })
}

// 获取表单值
function getFormData() {
  let callback = function nullFunc() {}
  let promise = new Promise(function (resolve, reject) {
    callback = function(formData, error) {
      !error ? resolve(formData) : reject(error);
    };
  });

  proxy.$refs['LeaveForm'].validate((valid) => {
    if (valid) {
      callback(formDataModel.value)
    } else {
      callback(formDataModel.value, '表单数据校验失败')
    }
  })

  return promise
}

// 获取表单key-类型数据(数据会存入表中,流程设计,回显时使用)
function getFormModuleType() {
  return new Promise((resolve) => {
    resolve(formDataModelType.value);
  });
}

// 获取表单组件属性列表(数据会存入表中,流程设计,回显时使用)
function getFieldWidgets() {
  return new Promise((resolve) => {
    resolve(fieldWidgets.value);
  });
}

// 禁用表单组件
function disableWidgets(widgetNames) {
  widgetNames.forEach(name => formDisabled.value[name] = true);
}

// 启用表单组件
function enableWidgets(widgetNames) {
  widgetNames.forEach(name => formDisabled.value[name] = false);
}

// 隐藏表单组件
function hideWidgets(widgetNames) {
  Object.keys(formHidden.value).forEach(name => {
    formHidden.value[name] = !widgetNames.includes(name);
  });
}

/* --- 自定义组件必须实现方法 ---end */

// 暴露数据-vue3写法
defineExpose({
  setFormData,
  getFormData,
  getFormModuleType,
  getFieldWidgets,
  disableWidgets,
  enableWidgets,
  hideWidgets,
});

</script>

<style lang="scss">
.el-input-number.full-width-input,
.el-cascader.full-width-input {
  width: 100% !important;
}

.el-form-item--medium {
  .el-radio {
    line-height: 36px !important;
  }

  .el-rate {
    margin-top: 8px;
  }
}

.el-form-item--small {
  .el-radio {
    line-height: 32px !important;
  }

  .el-rate {
    margin-top: 6px;
  }
}

.el-form-item--mini {
  .el-radio {
    line-height: 28px !important;
  }

  .el-rate {
    margin-top: 4px;
  }
}

.clear-fix:before,
.clear-fix:after {
  display: table;
  content: "";
}

.clear-fix:after {
  clear: both;
}

.float-right {
  float: right;
}

/* 组件宽度*/
.module-width {
  width: 50%;
}

.module-input-width {
  width: 50%;
}

</style>

<style lang="scss" scoped>
div.table-container {
  table.table-layout {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;

    td.table-cell {
      display: table-cell;
      height: 36px;
      border: 1px solid #e1e2e3;
    }
  }
}

div.tab-container {}

.label-left-align :deep(.el-form-item__label) {
  text-align: left;
}

.label-center-align :deep(.el-form-item__label) {
  text-align: center;
}

.label-right-align :deep(.el-form-item__label) {
  text-align: right;
}

.custom-label {}

.static-content-item {
  min-height: 20px;
  display: flex;
  align-items: center;

  :deep(.el-divider--horizontal) {
    margin: 0;
  }
}

</style>
